package sjtu.ist.warehouse4ws.action.file;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.struts2.json.annotations.JSON;
import org.apache.tools.ant.util.FileUtils;

import sjtu.ist.warehouse4ws.jcr.RepositoryMoudl;
import sjtu.ist.warehouse4ws.model.Department;
import sjtu.ist.warehouse4ws.model.Fileinfo;
import sjtu.ist.warehouse4ws.model.Functionpoint;
import sjtu.ist.warehouse4ws.model.Functions;
import sjtu.ist.warehouse4ws.model.Modelgroup;
import sjtu.ist.warehouse4ws.model.Permission;
import sjtu.ist.warehouse4ws.model.Permissionresources;
import sjtu.ist.warehouse4ws.model.Resource;
import sjtu.ist.warehouse4ws.model.Role;
import sjtu.ist.warehouse4ws.model.Rolepermissions;
import sjtu.ist.warehouse4ws.model.ShiroUser;
import sjtu.ist.warehouse4ws.security.MyRealm;
import sjtu.ist.warehouse4ws.service.DepartmentService;
import sjtu.ist.warehouse4ws.service.FileInfoService;
import sjtu.ist.warehouse4ws.service.ModelgroupService;
import sjtu.ist.warehouse4ws.service.PermissionService;
import sjtu.ist.warehouse4ws.service.PermissionresourcesService;
import sjtu.ist.warehouse4ws.service.ResourceService;
import sjtu.ist.warehouse4ws.service.RoleService;
import sjtu.ist.warehouse4ws.service.RolepermissionsService;
import sjtu.ist.warehouse4ws.service.ShiroUserService;
import sjtu.ist.warehouse4ws.tool.BaseAction;
import sjtu.ist.warehouse4ws.tool.MyUtils;
import sjtu.ist.warehouse4ws.tool.ParserFunctionpoint;
import sjtu.ist.warehouse4ws.tool.ParserOrg;
import sjtu.ist.warehouse4ws.tool.ParserProcess;
import sjtu.ist.warehouse4ws.tool.file.ModelPackage;
import sjtu.ist.warehouse4ws.tool.parser.PackageParser;

public class UploadFileAction extends BaseAction {
	private static final String ROOT = "upload\\";// 上传文件存放目录
	private static final String newline = PackageParser.newline;// 显示文本换行符

	// service
	private ShiroUserService shiroUserService;
	private RepositoryMoudl repositoryMoudlService;
	private ModelgroupService modelgroupService;
	private FileInfoService fileInfoService;
	private PermissionService permissionService;
	private PermissionresourcesService permissionresourcesService;
	private RoleService roleService;
	private RolepermissionsService rolepermissionsService;
	private DepartmentService departmentService;
	private ResourceService resourceService;

	// 输入
	private File myUpload;
	private String myUploadFileName;
	private String userName;// 用户名

	// 返回结果
	private String uploadResult="";
	private boolean success=true;
	private List<Fileinfo> otherModel = new ArrayList<Fileinfo>();
	
	// 权限验证
	private MyRealm myRealm;

	/**
	 * 上传模型文件压缩包
	 * 
	 * @return
	 */
	public String uploadPackage() {
		System.out.println("上传模型包。");
		DefaultSecurityManager securityManager = new DefaultSecurityManager();
		securityManager.setRealm(myRealm);
		SecurityUtils.setSecurityManager(securityManager);
		
		ShiroUser user = shiroUserService.findUser(userName);
		int companyId = user.getCompanyId();
		StringBuilder result = new StringBuilder("模型解析异常:" + newline);// 解析结果

		// 临时文件保存路径
		String savePath = getSession().getServletContext().getRealPath("/");
		savePath += ROOT + userName + "\\";

		// 写入上传文件
		MyUtils.upload(myUploadFileName, savePath, myUpload);

		// 检测模型一致性
		PackageParser packageParser = checkPackageConsistence(myUpload,
				savePath);
		String checkResult = packageParser.getResult();
		if (checkResult.length() > 0) {
			// 模型一致性不完整
			System.out.println("模型一致性不完整，上传失败。");
			result.append(checkResult);
			uploadResult = result.toString();

			// 删除临时文件
			FileUtils.delete(new File(savePath));
			FileUtils.delete(myUpload);
			return SUCCESS;
		}

		System.out.println("通过模型一致性校验，开始写入数据库。");
		// 导入组织模型
		importOrganizationModels(companyId,packageParser);
		
		System.out.println("组织模型信息导入成功");
		return SUCCESS;
	}

	/**
	 * 检测模型包一致性
	 * 
	 * @param file
	 * @return
	 */
	private PackageParser checkPackageConsistence(File file, String savePath) {
		PackageParser packageParser = new PackageParser(myUpload, savePath,myUploadFileName);
		// 检测模型一致性
		packageParser.checkConsistency();
		return packageParser;
	}

	/**
	 * 导入组织模型数据，存储所有模型文件信息
	 * @param companyId 公司ID
	 * @param packageParser 模型包解析器
	 * @return
	 */
	private String importOrganizationModels(int companyId, PackageParser packageParser) {

		// 临时文件保存路径
		String rootPath = getSession().getServletContext().getRealPath("/")
				+ ROOT;
		String savePath = rootPath + userName + "\\";

		int last = myUploadFileName.lastIndexOf(".");
		String groupName = myUploadFileName.substring(0, last);
		String group = myUploadFileName.substring(0, last);

		// 储存模型组基本信息
		Modelgroup modelgroup = new Modelgroup();
		modelgroup.setDescription("");
		modelgroup.setGroupName(groupName);
		int groupId = modelgroupService.save(modelgroup,companyId);

		// 存入模型库
		repositoryMoudlService.saveModelgroup(savePath,
				String.valueOf(companyId), groupName);
		// 提取模型版本号
		String version = repositoryMoudlService.getVersion(
				String.valueOf(companyId), groupName);
		// 更新模型版本号
		modelgroup.setVersion(version);
		modelgroupService.update(modelgroup,companyId);

		ModelPackage mp = packageParser.getMp();

		// 存储domain的fileinfo
		for (File f : mp.domainFiles) {
			Fileinfo fileinfo = new Fileinfo();
			fileinfo.setXmlpath(f.getAbsolutePath());
			fileinfo.setName(f.getName());
			fileinfo.setId(java.util.UUID.randomUUID().toString());
			fileinfo.setProject(group);
			fileinfo.setType(4);
			fileinfo.setGroupId(String.valueOf(groupId));
			fileinfo.setVersionId(version);
			
			fileInfoService.saveFileInfo(fileinfo,companyId);
			otherModel.add(fileinfo);
		}

		// 存储function的fileinfo
		for (File f : mp.functionFiles) {
			Fileinfo fileinfo = new Fileinfo();
			fileinfo.setXmlpath(f.getAbsolutePath());
			fileinfo.setName(f.getName());
			fileinfo.setId(java.util.UUID.randomUUID().toString());
			fileinfo.setProject(group);
			fileinfo.setType(2);
			fileinfo.setVersionId(version);
			fileinfo.setGroupId(String.valueOf(groupId));
			
			fileInfoService.saveFileInfo(fileinfo,companyId);
			otherModel.add(fileinfo);
		}

		// 存储process的fileinfo
		for (File f : mp.processFiles) {
			Fileinfo fileinfo = new Fileinfo();
			fileinfo.setXmlpath(f.getAbsolutePath());
			fileinfo.setName(f.getName());
			fileinfo.setId(java.util.UUID.randomUUID().toString());
			fileinfo.setProject(group);
			fileinfo.setType(1);
			fileinfo.setVersionId(version);
			fileinfo.setGroupId(String.valueOf(groupId));
			fileInfoService.saveFileInfo(fileinfo,companyId);
			otherModel.add(fileinfo);
		}

		// 存储organization的fileinfo
		// department,permission,resource,role,rolepermission,permissionresource
		for (File f : mp.organizationFiles) {
			Fileinfo fileinfo = new Fileinfo();
			fileinfo.setXmlpath(f.getAbsolutePath());
			fileinfo.setName(f.getName());
			fileinfo.setId(java.util.UUID.randomUUID().toString());
			fileinfo.setProject(group);
			fileinfo.setVersionId(version);
			fileinfo.setGroupId(String.valueOf(groupId));
			fileinfo.setType(3);

			fileInfoService.saveFileInfo(fileinfo,companyId);

			int deptNotParse = 0;
			ParserOrg parserOrg = new ParserOrg();
			List<Department> departmentList = parserOrg.parseDepartment(f
					.getAbsolutePath()); // 解析并存储部门
			for (Department department : departmentList) {
				department.setFileId(fileinfo.getId());
				department.setUid(java.util.UUID.randomUUID().toString());
				department.setGroupId(String.valueOf(groupId));
				department.setVersionId(version);
				deptNotParse = 1;
			}
			if (deptNotParse == 1)
				departmentService.save(departmentList,companyId);
			int permNotParse = 0;
			List<Permission> permissionList = parserOrg.parsePermission(f
					.getAbsolutePath()); // 解析并存储权限
			for (Permission permission : permissionList) {
				permNotParse = 1;
				permission.setFileId(fileinfo.getId());
				permission.setUid(java.util.UUID.randomUUID().toString());
				permission.setGroupId(String.valueOf(groupId));
				permission.setVersionId(version);
				permissionService.addPermission(permission,companyId);
			}
			int recNotParse = 0;
			List<Resource> resourceList = parserOrg.parseResource(f
					.getAbsolutePath()); // 解析并存储资源
			for (Resource resource : resourceList) {
				recNotParse = 1;
				resource.setFileId(fileinfo.getId());
				resource.setUid(java.util.UUID.randomUUID().toString());
				resource.setGroupId(String.valueOf(groupId));
				resource.setVersionId(version);
				resourceService.addResource(resource,companyId);
			}
			int roleNotParse = 0;
			List<Role> roleList = parserOrg.parseRole(f.getAbsolutePath()); // 解析并存储角色
			for (Role role : roleList) {

				roleNotParse = 1;
				role.setFileId(fileinfo.getId());
				role.setUid(java.util.UUID.randomUUID().toString());
				role.setGroupId(String.valueOf(groupId));
				role.setVersionId(version);
				roleService.addRole(role,companyId);
				// }
			}

			if (roleNotParse == 1 && permNotParse == 1) {
				List<Rolepermissions> rolepermissionsList = parserOrg
						.parseRolepermissions(f.getAbsolutePath()); // 解析并存储角色权限
				for (Rolepermissions rolepermissions : rolepermissionsList) {
					rolepermissions.setGroupId(String.valueOf(groupId));
					rolepermissions.setVersionId(version);
					rolepermissionsService.addRolepermissions(rolepermissions,companyId);
				}
			}

			if (permNotParse == 1 && recNotParse == 1) {
				List<Permissionresources> permissionresourcesList = parserOrg
						.parsePermissionresources(f.getAbsolutePath());
				for (Permissionresources permissionresources : permissionresourcesList) {
					permissionresources.setGroupId(String.valueOf(groupId));
					permissionresources.setVersionId(version);// 解析并纯初权限资源
					permissionresourcesService
							.addPermissionresources(permissionresources,companyId);
				}
			}
		}
		
		// 存储epc的fileinfo
		for (File f : mp.epcFiles) {
			Fileinfo fileinfo = new Fileinfo();
			fileinfo.setXmlpath(f.getAbsolutePath());
			fileinfo.setName(f.getName());
			fileinfo.setId(java.util.UUID.randomUUID().toString());
			fileinfo.setProject(group);
			fileinfo.setType(5);
			fileinfo.setVersionId(version);
			fileinfo.setGroupId(String.valueOf(groupId));

			fileInfoService.saveFileInfo(fileinfo,companyId);
			otherModel.add(fileinfo);
		}
		
		return String.valueOf(groupId);

	}

	// ///////////////////////////////////////////////////////////////
	// setters and getters

	public void setMyUpload(File myUpload) {
		this.myUpload = myUpload;
	}

	public void setMyUploadFileName(String myUploadFileName) {
		this.myUploadFileName = myUploadFileName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	/**
	 * @param shiroUserService
	 *            the shiroUserService to set
	 */
	public void setShiroUserService(ShiroUserService shiroUserService) {
		this.shiroUserService = shiroUserService;
	}

	/**
	 * @param repositoryMoudlService
	 *            the repositoryMoudlService to set
	 */
	public void setRepositoryMoudlService(RepositoryMoudl repositoryMoudlService) {
		this.repositoryMoudlService = repositoryMoudlService;
	}

	public void setModelgroupService(ModelgroupService modelgroupService) {
		this.modelgroupService = modelgroupService;
	}

	public void setFileInfoService(FileInfoService fileInfoService) {
		this.fileInfoService = fileInfoService;
	}

	public void setPermissionService(PermissionService permissionService) {
		this.permissionService = permissionService;
	}

	public void setPermissionresourcesService(
			PermissionresourcesService permissionresourcesService) {
		this.permissionresourcesService = permissionresourcesService;
	}

	public void setRoleService(RoleService roleService) {
		this.roleService = roleService;
	}

	public void setRolepermissionsService(
			RolepermissionsService rolepermissionsService) {
		this.rolepermissionsService = rolepermissionsService;
	}

	public void setResourceService(ResourceService resourceService) {
		this.resourceService = resourceService;
	}
	
	public void setDepartmentService(DepartmentService departmentService) {
		this.departmentService = departmentService;
	}

	public void setMyRealm(MyRealm myRealm) {
		this.myRealm = myRealm;
	}

	//返回内容 getters
	@JSON(name = "uploadResult")
	public String getUploadResult() {
		return uploadResult;
	}
	
	@JSON(name = "success")
	public boolean isSuccess() {
		return success;
	}

	@JSON(name = "otherModel")
	public List<Fileinfo> getOtherModel() {
		return otherModel;
	}
	
	@JSON(name = "totalOtherModel")
	public int getTotalOtherModel() {
		return otherModel.size();
	}
}
